package com.hy.mydesktop.client.mvc.window;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.internal.compiler.ast.ThisReference;

import com.extjs.gxt.desktop.client.Desktop;
import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.Window;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.hy.mydesktop.client.MyDesktop;
import com.hy.mydesktop.client.component.event.AppEvents;
import com.hy.mydesktop.client.component.factory.GxtComponentFactory;
import com.hy.mydesktop.client.component.mvc.event.EventStructureMetaModel;
import com.hy.mydesktop.client.component.mvc.factory.GxtComponentControlerFactory;
import com.hy.mydesktop.client.mvc.base.BaseController;
import com.hy.mydesktop.client.mvc.util.ControllerUtil;
import com.hy.mydesktop.client.rpc.ServiceInvoker;
import com.hy.mydesktop.client.rpc.ServiceInvokerAsync;
import com.hy.mydesktop.shared.persistence.domain.gxt.GxtComponentMetaModel;
import com.hy.mydesktop.shared.rpc.meta.GxtToSeamServiceParameter;
import com.hy.mydesktop.shared.rpc.meta.GxtToSeamServiceResult;
import com.hy.mydesktop.shared.util.log.MyLoggerUtil;

/**
 * 
 * <ul>
 * <li>开发作者：花宏宇</li>
 * <li>设计日期：2010-9-19；时间：上午11:19:35</li>
 * <li>类型名称：WindowController</li>
 * <li>设计目的：</li>
 * </ul>
 * <ul>
 * <b>修订编号：</b>
 * <li>修订日期：</li>
 * <li>修订作者：</li>
 * <li>修订原因：</li>
 * <li>修订内容：</li>
 * </ul>
 */
public class WindowController extends BaseController {

	private WindowPresenter windowPresenter;

	public WindowController() {
		// 可以动态配置
		// registerEventTypes(AppEvents.DESKTOP_SHORTCUT_ONCLICK_INIT);
		super();
		super.printControllerForInit(getClass());
	}

	@Override
	public void handleEvent(AppEvent event) {
		Map<String, Object> map = (Map<String, Object>) event.getData();
		EventStructureMetaModel eventStructureMetaModel = null;
		if (map != null) {
			eventStructureMetaModel = (EventStructureMetaModel) map
					.get("eventstructuremetamodel");
		}
		// EventStructureMetaModel eventStructureMetaModel
		// =(EventStructureMetaModel)((Map<String,
		// Object>)event.getData()).get("eventstructuremetamodel");

		if (ControllerUtil.isRootHandle(eventStructureMetaModel, this)) {

			// 0010
			/*
			 * if (AppEvents.DESKTOP_SUB_APPLICATION_INIT==event.getType()) {
			 * //System
			 * .err.println("DESKTOP_APPLICATION_INIT.getEventCode()"+AppEvents
			 * .DESKTOP_APPLICATION_INIT.getEventCode());
			 * //System.err.println("event.getType().getEventCode()"
			 * +event.getType().getEventCode());
			 *//**
			 * 初始化一个窗口及其附属结构的Controller时，需要比较之前设置的eventStructureMetaModel.
			 * getControllerId 这样才能区分到底初始化哪个一个窗口
			 * 转发给子节点之前，需要重新设置eventstructuremetamodel
			 * 设置eventstructuremetamodel.setControllerId(null);
			 */
			/*
				*//**
			 * 对于非初始化类别的操作，采用其他方式处理
			 */
			/*
			 * //if (eventStructureMetaModel==null||this.getId()==null||
			 * eventStructureMetaModel
			 * .getControllerId()==null||eventStructureMetaModel
			 * .getControllerId().equals(this.getId())) {
			 *//**
			 * 根据元模型，加载树状控制器 并注册到DIspacher
			 */
			/*
			 * 
			 * //ControllerUtil.registerController(gxtComponentMetaModel); if
			 * (ControllerUtil.isHandle(eventStructureMetaModel, this)) {
			 * 
			 * final ServiceInvokerAsync serviceInvoker =
			 * GWT.create(ServiceInvoker.class);
			 * 
			 * 
			 * final GxtToSeamServiceParameter gxtToSeamServiceParameter =
			 * (GxtToSeamServiceParameter)map.get("gxtToSeamServiceParameter");
			 * 
			 * 
			 * serviceInvoker.callService(gxtToSeamServiceParameter, new
			 * AsyncCallback<GxtToSeamServiceResult>() {
			 * 
			 * @Override public void onSuccess(GxtToSeamServiceResult result) {
			 * List<GxtComponentMetaModel> bmBaseModels = new
			 * LinkedList<GxtComponentMetaModel>(); ModelData modelData =
			 * result.getResult(); bmBaseModels =
			 * modelData.get("listOfModelData");
			 * 
			 * EventStructureMetaModel subEventStructureMetaModel = new
			 * EventStructureMetaModel();
			 * //subEventStructureMetaModel.setControllerId
			 * ("windowController2");
			 * //subEventStructureMetaModel.setRootControllerId
			 * ("windowController2"); for (GxtComponentMetaModel
			 * gxtComponentMetaModel : bmBaseModels) { BaseController
			 * baseController =(BaseController)GxtComponentControlerFactory.
			 * createGxtComponentController(gxtComponentMetaModel);
			 * 
			 * subEventStructureMetaModel.setRootControllerId(baseController.getId
			 * ());
			 * subEventStructureMetaModel.setControllerId(baseController.getId
			 * ());
			 * 
			 * List<Controller> controllers = Dispatcher.get().getControllers();
			 * Boolean contains = false; for (Controller controller :
			 * controllers) { if
			 * (((BaseController)controller).getId().equals(baseController
			 * .getId())) { contains = true; } } if (!contains) {
			 * Dispatcher.get().addController(baseController); }
			 * 
			 * } Map<String,Object> oneDispacherEventTypeData = new
			 * HashMap<String, Object>(); //需要把Desktop传递给下一个事件
			 * oneDispacherEventTypeData.put("desktop",
			 * windowPresenter.getDesktop()); //TODO 需要把存放Window的容器，传到下一个事件中
			 * oneDispacherEventTypeData.put("windowContainer",
			 * windowPresenter.getWindow());
			 * oneDispacherEventTypeData.put("eventstructuremetamodel",
			 * subEventStructureMetaModel);
			 * Dispatcher.forwardEvent(AppEvents.DESKTOP_APPLICATION_INIT
			 * ,oneDispacherEventTypeData); }
			 * 
			 * @Override public void onFailure(Throwable caught) {
			 * System.err.println("#### Rpc Exception is beginning ####");
			 * System.err.println(caught);
			 * System.err.println("#### Rpc Exception is over #### ");
			 * caught.printStackTrace(); } });
			 * 
			 * 
			 * } }
			 */
			// 0007
			if (AppEvents.DESKTOP_WINDOWAPPLICATION_INIT == event.getType()) {
				// System.err.println("DESKTOP_APPLICATION_INIT.getEventCode()"+AppEvents.DESKTOP_APPLICATION_INIT.getEventCode());
				// System.err.println("event.getType().getEventCode()"+event.getType().getEventCode());
				/**
				 * 初始化一个窗口及其附属结构的Controller时，需要比较之前设置的eventStructureMetaModel.
				 * getControllerId 这样才能区分到底初始化哪个一个窗口
				 * 转发给子节点之前，需要重新设置eventstructuremetamodel
				 * 设置eventstructuremetamodel.setControllerId(null);
				 */
				/**
				 * 对于非初始化类别的操作，采用其他方式处理
				 */
				// if
				// (eventStructureMetaModel==null||this.getId()==null||eventStructureMetaModel.getControllerId()==null||eventStructureMetaModel.getControllerId().equals(this.getId()))
				// {
				if (ControllerUtil.isHandle(eventStructureMetaModel, this)) {

					forwardToView(windowPresenter, event);
					System.out
							.println("WindowController------------AppEvents.DESKTOP_APPLICATION_INIT");
					/**
					 * 由于Window，是组件中的，顶级元素，需要单独保存与处理
					 */
					map.put("root", windowPresenter.getWindow());
					/**
					 * 获取Controller对应的View的组件Component 把Component，作为事件的一部分，向下传递
					 * map.put("parent", windowView.getWindow()); 此方法错误
					 */
					Map<BaseController, Component> subMap = new HashMap<BaseController, Component>();
					subMap.put(this, windowPresenter.getWindow());
					/**
					 * 把Controller和,与之对应的Component放入Map（为了方便查找Component的父元素）
					 */
					map.put("controllerandcomponent", subMap);
					/**
					 * 如何知道事件已经转发完毕
					 * 
					 * 方法1 ： 计数器
					 */

					if (this.getChildren() != null
							&& this.getChildren().size() > 0) {
						/**
						 * 将事件转发给子节点，及子控制器 注:当前控制器，含有子节点的时候，必不可少
						 * 
						 * 采用先序遍历的方式---树
						 */

						/**
						 * 转发之前，需要重新设置eventstructuremetamodel
						 * 设置eventstructuremetamodel.setControllerId(null);
						 */
						eventStructureMetaModel.setControllerId(null);
						map.put("eventstructuremetamodel",
								eventStructureMetaModel);
						this.forwardToChild(new AppEvent(
								AppEvents.DESKTOP_WINDOWAPPLICATION_INIT, map));
					} /*
					 * else {
					 */
					/**
					 * 如果当前控制器，有子节点，则向下转发事件， 否则渲染组件，即渲染顶级元素 如何渲染顶级元素，即Window ？
					 */
					/*
					 * forwardToView(windowView,
					 * AppEvents.DESKTOP_APPLICATION_RENDER,event.getData()); }
					 */

					ControllerUtil.isRenderer(map);
					Dispatcher.forwardEvent(
							AppEvents.DESKTOP_APPLICATION_RENDER, map);
				}
			}

			// 0008
			else if (AppEvents.DESKTOP_APPLICATION_RENDER == event.getType()) {
				// if
				// (eventStructureMetaModel==null||this.getId()==null||eventStructureMetaModel.getControllerId()==null||eventStructureMetaModel.getControllerId().equals(this.getId()))
				// {
				if (ControllerUtil.isHandle(eventStructureMetaModel, this)) {

					System.out
							.println("WindowController------------AppEvents.DESKTOP_APPLICATION_RENDER");

					/**
					 * 如果当前控制器，有子节点，则向下转发事件， 否则渲染组件，即渲染顶级元素 如何渲染顶级元素，即Window ？
					 * forwardToView(View view, AppEvent event)
					 */
					forwardToView(windowPresenter, event);
				}
			}

			// 当对于当前的事件，都没有合适的处理方式的时候，转发给子节点Controller
			else {
				this.forwardToChild(event);
			}
		}

		/*
		 * 枚举每一个可能需要响应的事件，以及其需要的处理方式 ifelse switch (key) { case value:
		 * 
		 * break;
		 * 
		 * default: break; }
		 */
	}

	public void initialize() {
		Window window = GxtComponentFactory
				.createOneGxtComponent(getGxtComponentMetaNodeModel());
		
		WindowDisplay windowView = new WindowDisplay(window);

		/*
		 * if (this.getParent()==null||this.getParent().equals("")) {
		 * MyLoggerUtil.printWarn(getClass(), "当前Controller，没有parent！"); }else {
		 * // 构建控件的树形结构
		 * ((BaseController)this.getParent()).getPresenter().getDisplay
		 * ().add(window);
		 * 
		 * }
		 */
		windowPresenter = new WindowPresenter(this, windowView);
		//Window w;
	    /*if (ce instanceof MenuEvent) {
	      MenuEvent me = (MenuEvent) ce;
	      w = me.getItem().getData("window");
	    } else {
	      w = ce.getComponent().getData("window");
	    }*/
		/*Desktop desktop = Registry.get(MyDesktop.DESKTOP);
	    if (!desktop.getWindows().contains(window)) {
	      desktop.addWindow(window);
			window.show();

	    }*/
	    /*if (w != null && !w.isVisible()) {
	      w.show();
	    } else {
	      w.toFront();
	    }*/
//		buildComponentStructure(this, window);
		// TODO this.setPresenter(windowPresenter);有待实验
	}

	protected void onError(AppEvent ae) {
		System.out.println("error: " + ae.<Object> getData());
	}

}
